﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace BDSimpleStatus.Models
{
    public class BdssRepository
    {
        BdssEntities context = new BdssEntities();
        private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

        public ServerCheckModel GetServerCheckModel(int id)
        {
            var r = from sc in context.ServerChecks
                    where sc.Id == id
                    select sc;
            ServerCheck svrck = r.FirstOrDefault();
            if (svrck != null)
                return ServerCheckDbToModel(svrck);
            else
            {
                logger.Warn("GetServerCheckModel didn't match to id and return no records, new ServerCheckModel class returned");
                return new ServerCheckModel();
            }
        }
        /// <summary>
        /// Updates server check record
        /// </summary>
        /// <param name="scm">ServerCheckModel to be updated in database</param>
        /// <returns></returns>
        public bool UpdateServerCheck(ServerCheckModel scm)
        {
            return UpdateServerCheck(scm, false);
        }
        /// <summary>
        /// Updates a server check record
        /// </summary>
        /// <param name="scm">ServerCheckModel to be updated in database</param>
        /// <param name="IgnoreLastUpdated">Last Updated is read only during edits, ignore the value</param>
        /// <returns>Success?</returns>
        public bool UpdateServerCheck(ServerCheckModel scm, bool IgnoreLastUpdated)
        {
            ServerCheck srvchk = context.ServerChecks.First(x => x.Id == scm.Id);
            srvchk = ServerCheckModelToDb(scm, srvchk, IgnoreLastUpdated);
            try
            {
                context.SaveChanges();
                return true;
            }
            catch(Exception ex)
            {
                logger.ErrorException("UpdateServerCheck error", ex);
                return false;
            }
        }

        public bool UpdateServerCheckList(List<ServerCheckModel> scml)
        {
            foreach(ServerCheckModel scm in scml)
            {
                UpdateServerCheck(scm);
                //TODO:Some type of check here
            }
            return true;
        }

        public bool AddServerCheck(ServerCheckModel scm)
        {
            ServerCheck srvchk = ServerCheckModelToDb(scm);
            try
            {
                context.AddToServerChecks(srvchk);
                context.SaveChanges();
                return true;
            }
            catch(Exception ex)
            {
                logger.ErrorException("AddServerCheck error", ex);
                return false;
            }
        }

        public bool DeleteServerCheck(ServerCheckModel scm)
        {
            //ServerCheck srvchk = ServerCheckModelToDb(scm);
            try
            {
                var r = from sc in context.ServerChecks
                        where sc.Id == scm.Id
                        select sc;

                context.DeleteObject(r.First());
                context.SaveChanges();
                context.AcceptAllChanges();
                return true;
            }
            catch (Exception ex)
            {
                logger.ErrorException("DeleteServerCheck Exception", ex);
                return false;
            }
        }

        public List<ServerCheckModel> GetServerCheckModelList()
        {
            var r = from sc in context.ServerChecks
                    select sc;
            return CreateServerCheckModelListFromServerCheckCollection(r);
        }
        /// <summary>
        /// Gets a list of checks which are ready to be checked 
        /// </summary>
        /// <returns></returns>
        public List<ServerCheckModel> GetServersToCheck()
        {
            var r = from sc in context.ServerChecks
                    where sc.NextCheckDate <= DateTime.Now && sc.IsEnabled
                    select sc;
            return CreateServerCheckModelListFromServerCheckCollection(r);
        }

        private List<ServerCheckModel> CreateServerCheckModelListFromServerCheckCollection(IQueryable<ServerCheck> iqsc)
        {
            List<ServerCheckModel> scml = new List<ServerCheckModel>();
            foreach (var sc in iqsc)
            {
                scml.Add(ServerCheckDbToModel(sc));
            }
            return scml;
        }

        private ServerCheckModel ServerCheckDbToModel(ServerCheck db)
        {
            ServerCheckModel model = new ServerCheckModel();
            return ServerCheckDbToModel(db, model);
        }

        private ServerCheckModel ServerCheckDbToModel(ServerCheck db, ServerCheckModel model)
        {
            model.Id = db.Id;
            model.Name = db.Name;
            model.URL = db.URL;
            model.CheckPing = db.CheckPing;
            model.CheckHttp = db.CheckHttp;
            model.Frequency = db.Frequency;
            model.NextCheckDate = db.NextCheckDate;
            model.LastCheckDate = db.LastCheckDate;
            model.Description = db.Description;
            model.IsPingOk = db.IsPingOk;
            model.IsHttpOk = db.IsHttpOk;
            model.IsEnabled = db.IsEnabled;
            model.Message = db.Message;
            return model;
        }

        private ServerCheck ServerCheckModelToDb(ServerCheckModel model)
        {
            ServerCheck db = new ServerCheck();
            return ServerCheckModelToDb(model, db);
        }

        private ServerCheck ServerCheckModelToDb(ServerCheckModel model, ServerCheck db)
        {
            return ServerCheckModelToDb(model, db, false);
        }

        private ServerCheck ServerCheckModelToDb(ServerCheckModel model, ServerCheck db, bool IgnoreLastCheckDate)
        {
            db.Id = model.Id;
            db.Name = model.Name;
            db.URL = model.URL;
            db.CheckPing = model.CheckPing;
            db.CheckHttp = model.CheckHttp;
            db.Frequency = model.Frequency;
            db.NextCheckDate = model.NextCheckDate;
            if (!IgnoreLastCheckDate)
                db.LastCheckDate = model.LastCheckDate == null? Convert.ToDateTime("1900-01-01") : (DateTime)model.LastCheckDate;
            db.Description = model.Description == null ? string.Empty : model.Description;
            db.IsPingOk = model.IsPingOk;
            db.IsHttpOk = model.IsHttpOk;
            db.IsEnabled = model.IsEnabled;
            db.Message = model.Message == null ? string.Empty : model.Message;
            return db;
        }

    }
}